

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=auto>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/egg.png">
  <link rel="icon" href="/img/egg.png">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="author" content="十一的蛋炒饭">
  <meta name="keywords" content="">
  
    <meta name="description" content="1、数据库DB（DataBase） 是存储和管理数据的仓库。 DBMS（DataBase Management System）数据库管理系统，是一款操作和管理数据库的大型软件。 SQL（Structured Query Language） ，表示操作关系型数据库的编程语言，定义了一套操作关系型数据库统一的标准。 常见的数据库有：    数据库类型 描述    Oracle 收费的大型数据库，Ora">
<meta property="og:type" content="article">
<meta property="og:title" content="MySQL 学习笔记1 | 数据库、约束、常见数据类型、DDL、DML、DQL、MySQL多表设计、多表查询、MySQL事务、索引">
<meta property="og:url" content="http://example.com/2024/03/13/MySQL-%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B01-%E6%95%B0%E6%8D%AE%E5%BA%93%E3%80%81%E7%BA%A6%E6%9D%9F%E3%80%81%E5%B8%B8%E8%A7%81%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E3%80%81DDL%E3%80%81DML%E3%80%81DQL%E3%80%81MySQL%E5%A4%9A%E8%A1%A8%E8%AE%BE%E8%AE%A1%E3%80%81%E5%A4%9A%E8%A1%A8%E6%9F%A5%E8%AF%A2%E3%80%81MySQL%E4%BA%8B%E5%8A%A1%E3%80%81%E7%B4%A2%E5%BC%95/index.html">
<meta property="og:site_name" content="十一的蛋炒饭的博客">
<meta property="og:description" content="1、数据库DB（DataBase） 是存储和管理数据的仓库。 DBMS（DataBase Management System）数据库管理系统，是一款操作和管理数据库的大型软件。 SQL（Structured Query Language） ，表示操作关系型数据库的编程语言，定义了一套操作关系型数据库统一的标准。 常见的数据库有：    数据库类型 描述    Oracle 收费的大型数据库，Ora">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403121233955.png">
<meta property="og:image" content="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403121243805.png">
<meta property="og:image" content="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403121251535.png">
<meta property="og:image" content="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403121254580.png">
<meta property="og:image" content="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403121308407.png">
<meta property="og:image" content="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403121502441.png">
<meta property="og:image" content="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403121752385.png">
<meta property="og:image" content="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403122010618.png">
<meta property="og:image" content="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403130228111.png">
<meta property="og:image" content="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403130228551.png">
<meta property="og:image" content="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403130458224.png">
<meta property="og:image" content="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403130504081.png">
<meta property="og:image" content="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403130506375.png">
<meta property="article:published_time" content="2024-03-13T03:11:00.000Z">
<meta property="article:modified_time" content="2024-03-13T03:11:32.110Z">
<meta property="article:author" content="十一的蛋炒饭">
<meta property="article:tag" content="MySQL">
<meta property="article:tag" content="多表查询">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403121233955.png">
  
  
  
  <title>MySQL 学习笔记1 | 数据库、约束、常见数据类型、DDL、DML、DQL、MySQL多表设计、多表查询、MySQL事务、索引 - 十一的蛋炒饭的博客</title>

  <link  rel="stylesheet" href="https://lib.baomitu.com/twitter-bootstrap/4.6.1/css/bootstrap.min.css" />



  <link  rel="stylesheet" href="https://lib.baomitu.com/github-markdown-css/4.0.0/github-markdown.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/hint.css/2.7.0/hint.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css" />



<!-- 主题依赖的图标库，不要自行修改 -->
<!-- Do not modify the link that theme dependent icons -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_hj8rtnfg7um.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_lbnruvf0jn.css">


<link  rel="stylesheet" href="/css/main.css" />


  <link id="highlight-css" rel="stylesheet" href="/css/highlight.css" />
  
    <link id="highlight-css-dark" rel="stylesheet" href="/css/highlight-dark.css" />
  




  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    Fluid.ctx = Object.assign({}, Fluid.ctx)
    var CONFIG = {"hostname":"example.com","root":"/","version":"1.9.7","typing":{"enable":true,"typeSpeed":60,"cursorChar":"","loop":false,"scope":["home"]},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"left","visible":"hover","icon":"§"},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"code_language":{"enable":true,"default":"TEXT"},"copy_btn":true,"image_caption":{"enable":true},"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"placement":"right","headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"follow_dnt":true,"baidu":null,"google":{"measurement_id":null},"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null,"path":"window.location.pathname","ignore_local":false}},"search_path":"/local-search.xml","include_content_in_search":true};

    if (CONFIG.web_analytics.follow_dnt) {
      var dntVal = navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
      Fluid.ctx.dnt = dntVal && (dntVal.startsWith('1') || dntVal.startsWith('yes') || dntVal.startsWith('on'));
    }
  </script>
  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
  


  
<meta name="generator" content="Hexo 7.1.1"></head>


<body>
  

  <header>
    

<div class="header-inner" style="height: 70vh;">
  <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/">
      <strong>十一的蛋炒饭 的博客</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/" target="_self">
                <i class="iconfont icon-home-fill"></i>
                <span>首页</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/" target="_self">
                <i class="iconfont icon-archive-fill"></i>
                <span>归档</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/" target="_self">
                <i class="iconfont icon-category-fill"></i>
                <span>分类</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/" target="_self">
                <i class="iconfont icon-tags-fill"></i>
                <span>标签</span>
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/" target="_self">
                <i class="iconfont icon-user-fill"></i>
                <span>关于</span>
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              <i class="iconfont icon-search"></i>
            </a>
          </li>
          
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">
              <i class="iconfont icon-dark" id="color-toggle-icon"></i>
            </a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

  

<div id="banner" class="banner" parallax=true
     style="background: url('/img/win7.jpg') no-repeat center center; background-size: cover;">
  <div class="full-bg-img">
    <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
      <div class="banner-text text-center fade-in-up">
        <div class="h2">
          
            <span id="subtitle">MySQL 学习笔记1 | 数据库、约束、常见数据类型、DDL、DML、DQL、MySQL多表设计、多表查询、MySQL事务、索引</span>
          
        </div>

        
          
  <div class="mt-3">
    
    
      <span class="post-meta">
        <i class="iconfont icon-date-fill" aria-hidden="true"></i>
        <time datetime="2024-03-13 11:11" pubdate>
          2024年3月13日 上午
        </time>
      </span>
    
  </div>

  <div class="mt-1">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-chart"></i>
        
          7.6k 字
        
      </span>
    

    
      <span class="post-meta mr-2">
        <i class="iconfont icon-clock-fill"></i>
        
        
        
          64 分钟
        
      </span>
    

    
    
  </div>


        
      </div>

      
    </div>
  </div>
</div>

</div>

  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="side-col d-none d-lg-block col-lg-2">
      
  <aside class="sidebar category-bar" style="margin-right: -1rem">
    





<div class="category-list">
  
  
    
    
    
    <div class="category row nomargin-x">
      <a class="category-item 
          list-group-item category-item-action col-10 col-md-11 col-xm-11" title="MySQL"
        id="heading-62a004b95946bb97541afa471dcca73a" role="tab" data-toggle="collapse" href="#collapse-62a004b95946bb97541afa471dcca73a"
        aria-expanded="true"
      >
        MySQL
        <span class="list-group-count">(1)</span>
        <i class="iconfont icon-arrowright"></i>
      </a>
      
      <div class="category-collapse collapse show" id="collapse-62a004b95946bb97541afa471dcca73a"
           role="tabpanel" aria-labelledby="heading-62a004b95946bb97541afa471dcca73a">
        
        
          
  <div class="category-post-list">
    
    
      
      
        <a href="/2024/03/13/MySQL-%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B01-%E6%95%B0%E6%8D%AE%E5%BA%93%E3%80%81%E7%BA%A6%E6%9D%9F%E3%80%81%E5%B8%B8%E8%A7%81%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E3%80%81DDL%E3%80%81DML%E3%80%81DQL%E3%80%81MySQL%E5%A4%9A%E8%A1%A8%E8%AE%BE%E8%AE%A1%E3%80%81%E5%A4%9A%E8%A1%A8%E6%9F%A5%E8%AF%A2%E3%80%81MySQL%E4%BA%8B%E5%8A%A1%E3%80%81%E7%B4%A2%E5%BC%95/" title="MySQL 学习笔记1 | 数据库、约束、常见数据类型、DDL、DML、DQL、MySQL多表设计、多表查询、MySQL事务、索引"
           class="list-group-item list-group-item-action
           active">
          <span class="category-post">MySQL 学习笔记1 | 数据库、约束、常见数据类型、DDL、DML、DQL、MySQL多表设计、多表查询、MySQL事务、索引</span>
        </a>
      
    
  </div>

        
      </div>
    </div>
  
</div>


  </aside>


    </div>

    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div id="board">
          <article class="post-content mx-auto">
            <h1 id="seo-header">MySQL 学习笔记1 | 数据库、约束、常见数据类型、DDL、DML、DQL、MySQL多表设计、多表查询、MySQL事务、索引</h1>
            
              <p id="updated-time" class="note note-info" style="display: none">
                
                  
                    本文最后更新于 2024-03-13T11:11:32+08:00
                  
                  

                
              </p>
            
            
              <div class="markdown-body">
                
                <h2 id="1、数据库"><a href="#1、数据库" class="headerlink" title="1、数据库"></a>1、数据库</h2><p><strong>DB（DataBase）</strong> 是存储和管理数据的仓库。</p>
<p><strong>DBMS（DataBase Management System）</strong>数据库管理系统，是一款操作和管理数据库的大型软件。</p>
<p><strong>SQL（Structured Query Language）</strong> ，表示操作关系型数据库的编程语言，定义了一套操作关系型数据库统一的标准。</p>
<p>常见的数据库有：</p>
<table>
<thead>
<tr>
<th>数据库类型</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>Oracle</td>
<td>收费的大型数据库，Oracle公司的产品。</td>
</tr>
<tr>
<td>MySQL</td>
<td>开源免费的中小型数据库。Sun 公司收购了MySQL，而 Oracle 公司收购了 Sun公司。</td>
</tr>
<tr>
<td>SQL Server</td>
<td>MicroSoft 公司收费的中型的数据库。C#、.Net等语言常使用。</td>
</tr>
<tr>
<td>PostgreSQL</td>
<td>开源免费中小型的数据库。</td>
</tr>
<tr>
<td>DB2</td>
<td>IBM公司的大型收费数据库产品。</td>
</tr>
<tr>
<td>SQLite</td>
<td>嵌入式的微型数据库。如：作为 Android 内置数据库。</td>
</tr>
<tr>
<td>MariaDB</td>
<td>开源免费的中小型的数据库。</td>
</tr>
</tbody></table>
<h2 id="2、-MySQL-概述"><a href="#2、-MySQL-概述" class="headerlink" title="2、 MySQL 概述"></a>2、 MySQL 概述</h2><h3 id="2-1-MySQL的安装"><a href="#2-1-MySQL的安装" class="headerlink" title="2.1 MySQL的安装"></a>2.1 MySQL的安装</h3><p><a target="_blank" rel="noopener" href="https://www.mysql.com/">MySQL 官方</a> 提供了两种不同的版本：</p>
<p><strong>商业版本（MySQL Enterprise Edition）</strong>：收费，可使用30天，官方提供技术支持。</p>
<p><strong>社区版本（MySQL Community Server）</strong>：免费，MySQL不提供任何技术支持。</p>
<p>官方下载地址：<a target="_blank" rel="noopener" href="https://dev.mysql.com/downloads/mysql/">https://dev.mysql.com/downloads/mysql/</a></p>
<p><code>注：MySQL安装目录不能存在中文</code></p>
<p>安装好后，MySQL默认目录在</p>
<figure class="highlight livescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs livescript">C:<span class="hljs-string">\Program</span> Files<span class="hljs-string">\MySQL</span><br></code></pre></td></tr></table></figure>

<p><strong>第1步：配置环境变量</strong></p>
<p>MySQL安装好后，需要配置环境变量，和 JDK类似，将 MySQL目录中的 bin文件夹添加到环境变量的 PATH 中。</p>
<p><strong>第2步：初始化MySQL</strong></p>
<p>配置好环境变量后，控制台可通过 mysql 指令来使用 MySQL，接下来需要进行初始化data目录</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">mysqld --initialize-insecure<br></code></pre></td></tr></table></figure>

<p>等待一段时间后，若没报错，则可以查看以下MySQL目录中有没有data目录生成。</p>
<p><strong>第3步：注册系统服务</strong></p>
<p>在控制台输入命令以便注册 MySQL 服务。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">mysqld -install<br></code></pre></td></tr></table></figure>

<p>查看是否注册成功，在系统中搜索服务，查看是否包含 MySQL：</p>
<p><img src="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403121233955.png" srcset="/img/loading.gif" lazyload alt="image-20240312123322886"></p>
<p><strong>第4步：启动&#x2F;停止 MySQL 服务</strong></p>
<p>启动 MySQL 服务</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">net start mysql<br></code></pre></td></tr></table></figure>

<p>停止 MySQL 服务</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">net stop mysql<br></code></pre></td></tr></table></figure>



<h3 id="2-2-MySQL-登录"><a href="#2-2-MySQL-登录" class="headerlink" title="2.2 MySQL 登录"></a>2.2 MySQL 登录</h3><p>控制台输入命令进行登录（用户名通常用 <code>root</code> 即可）：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">mysql -u用户名 -p密码 [-h数据库服务器IP地址(默认为localhost) -P端口号(默认为3306)]<br></code></pre></td></tr></table></figure>



<h3 id="2-3-MySQL-数据模型"><a href="#2-3-MySQL-数据模型" class="headerlink" title="2.3 MySQL 数据模型"></a>2.3 MySQL 数据模型</h3><p><strong>RDBMS，关系型数据库</strong> ：建立在关系模型基础上，由多张相互连接的二维表组成的数据库。</p>
<p><strong>特点：</strong></p>
<ul>
<li>使用表存储怇，格式统一，便于维护。</li>
<li>使用SQL语言操作，标准统一，使用方便，可用于复杂查询。</li>
</ul>
<p><img src="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403121243805.png" srcset="/img/loading.gif" lazyload alt="image-20240312124355735"></p>
<h2 id="3、SQL-语句"><a href="#3、SQL-语句" class="headerlink" title="3、SQL 语句"></a>3、SQL 语句</h2><h3 id="3-1-SQL-简介"><a href="#3-1-SQL-简介" class="headerlink" title="3.1 SQL 简介"></a>3.1 SQL 简介</h3><p><strong>SQL：</strong>一门操作关系型数据库的编程语言，定义操作所有关系型数据库的统一标准。</p>
<p><strong>SQL 语句通用语法：</strong></p>
<ul>
<li>SQL 语句可单行或多行书写，以分号结尾。</li>
<li>SQL 语句可使用空格或缩进，来增强语言的可读性。</li>
<li>MySQL 数据库的 SQL 语句不区分大小写。</li>
<li>注释：<ul>
<li>单行注释：<code>-- 注释内容</code> 或 <code># 注释内容</code>(MySQL特有的)。</li>
<li>多行注释：<code>/* 注释内容 */</code>。</li>
</ul>
</li>
</ul>
<h3 id="3-2-SQL-分类"><a href="#3-2-SQL-分类" class="headerlink" title="3.2 SQL 分类"></a>3.2 SQL 分类</h3><p>SQL 语句通常被分为四大类：</p>
<table>
<thead>
<tr>
<th>分类</th>
<th>全称</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>DDL</td>
<td>Data Definition Language</td>
<td>数据定义语言，用来定义数据库对象（数据库，表，字段）。</td>
</tr>
<tr>
<td>DML</td>
<td>Data Manipulation Language</td>
<td>数据操作语言，用来对数据表中的数据进行增删改。</td>
</tr>
<tr>
<td>DQL</td>
<td>Data Query Language</td>
<td>数据查询语言，用来查询数据库中表的记录。</td>
</tr>
<tr>
<td>DCL</td>
<td>Data Control Language</td>
<td>数据控制语言，用来创建数据表用户、控制数据库的访问权限。</td>
</tr>
</tbody></table>
<p><img src="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403121251535.png" srcset="/img/loading.gif" lazyload alt="image-20240312125115361"></p>
<p><img src="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403121254580.png" srcset="/img/loading.gif" lazyload alt="Web开发中数据库设计的流程"></p>
<h2 id="4、MyQSL-图形化工具"><a href="#4、MyQSL-图形化工具" class="headerlink" title="4、MyQSL 图形化工具"></a>4、MyQSL 图形化工具</h2><p>MySQL 操作若只通过控制台，会非常麻烦，所以建议用图形化工具来管理 MySQL数据库。</p>
<p>常见的图形化工具有：</p>
<p><img src="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403121308407.png" srcset="/img/loading.gif" lazyload alt="image-20240312130839363"></p>
<p>笔者习惯用 <code>Navicat</code>。</p>
<h2 id="5、MySQL数据库操作"><a href="#5、MySQL数据库操作" class="headerlink" title="5、MySQL数据库操作"></a>5、MySQL数据库操作</h2><h3 id="5-1-MySQL中的约束"><a href="#5-1-MySQL中的约束" class="headerlink" title="5.1 MySQL中的约束"></a>5.1 MySQL中的约束</h3><p><strong>概念：</strong>约束是作用于表中字段上的规则，用于限制存储在表中的数据。</p>
<p><strong>目的：</strong>保证数据库中数据的正确性、有效性和完整性。</p>
<table>
<thead>
<tr>
<th>约束</th>
<th>描述</th>
<th>关键字</th>
</tr>
</thead>
<tbody><tr>
<td>非空约束</td>
<td>限制该字段值不能为 null</td>
<td>not null</td>
</tr>
<tr>
<td>唯一约束</td>
<td>保证字段的所有数据都是唯一、不重复的</td>
<td>unique</td>
</tr>
<tr>
<td>主键约束</td>
<td>主键是一行数据的唯一标识，要求非空且唯一</td>
<td>primary key (auto_increment 自增)</td>
</tr>
<tr>
<td>默认约束</td>
<td>保存数据时，若未指定该字段值，则采用默认值</td>
<td>default</td>
</tr>
<tr>
<td>外键约束</td>
<td>让两张表的数据建立连接，保证数据的一致性和完整性</td>
<td>foreign key</td>
</tr>
</tbody></table>
<h3 id="5-2-MySQL-常见数据类型"><a href="#5-2-MySQL-常见数据类型" class="headerlink" title="5.2 MySQL 常见数据类型"></a>5.2 MySQL 常见数据类型</h3><h4 id="5-2-1-数值类型"><a href="#5-2-1-数值类型" class="headerlink" title="5.2.1 数值类型"></a>5.2.1 数值类型</h4><table>
<thead>
<tr>
<th>类型</th>
<th>大小（Byte）</th>
<th>有符号（SINGLE）范围</th>
<th>无符号（UNSINGLE）范围</th>
<th>描述</th>
<th>备注</th>
</tr>
</thead>
<tbody><tr>
<td>tinyint</td>
<td>1</td>
<td>(-128, 127)</td>
<td>(0, 255)</td>
<td>小整数值</td>
<td></td>
</tr>
<tr>
<td>smallint</td>
<td>2</td>
<td>(-32768, 32767)</td>
<td>(0, 65535)</td>
<td>大整数值</td>
<td></td>
</tr>
<tr>
<td>mediumint</td>
<td>3</td>
<td>(-8388608, 8388607)</td>
<td>(0, 16777215)</td>
<td>大整数值</td>
<td></td>
</tr>
<tr>
<td>int</td>
<td>4</td>
<td>(-214748368, 214783647)</td>
<td>(0, 4294967295)</td>
<td>大整数值</td>
<td></td>
</tr>
<tr>
<td>bigint</td>
<td>8</td>
<td>($-2^{63}, 2^{63}-1$)</td>
<td>（0， $2^{64}-1$ )</td>
<td>极大整数值</td>
<td></td>
</tr>
<tr>
<td>float</td>
<td>4</td>
<td>(-3.40282366 E+38，3.402823466351 E+38)</td>
<td>0 和 (1.175494351 E-38, 3.402823466 E+38)</td>
<td>单精度浮点数值</td>
<td>float(5, 2)：5表示整个数字长度，2表示小数点位个数</td>
</tr>
<tr>
<td>double</td>
<td>8</td>
<td>(-1.7976931348623157 E+308, 1.7976931348623157 E+308)</td>
<td>0 和 (2.2250738585072014 E-308, 1.7976931348623157 E+308)</td>
<td>双精度浮点数值</td>
<td>doubel(5, 2)：5表示整个数字长度，2 表示小数点位个数</td>
</tr>
<tr>
<td>decimal</td>
<td></td>
<td></td>
<td></td>
<td>小数值（精度更高）</td>
<td>decimal(5, 2)：5表示整个数字长度，2表示小数点位数</td>
</tr>
</tbody></table>
<h4 id="5-2-2-字符串类型"><a href="#5-2-2-字符串类型" class="headerlink" title="5.2.2 字符串类型"></a>5.2.2 字符串类型</h4><table>
<thead>
<tr>
<th>类型</th>
<th>大小（Byte:字节)</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>char</td>
<td>0-255</td>
<td>定长字符串</td>
</tr>
<tr>
<td><strong>varchar</strong></td>
<td>0-65535</td>
<td>变长字符串</td>
</tr>
<tr>
<td>tinyblob</td>
<td>0-255</td>
<td>不超过 255个字符的二进制数据</td>
</tr>
<tr>
<td>tinytext</td>
<td>0-255</td>
<td>短文本字符串</td>
</tr>
<tr>
<td>blob</td>
<td>0-65535</td>
<td>二进制形式的长文本数据</td>
</tr>
<tr>
<td>text</td>
<td>0-65535</td>
<td>长文本数据</td>
</tr>
<tr>
<td>mediumblob</td>
<td>0-16777215</td>
<td>二进制形式的中等长度文本数据</td>
</tr>
<tr>
<td>longblob</td>
<td>0-4294967295</td>
<td>二进制形式的极大文本数据</td>
</tr>
<tr>
<td>longtext</td>
<td>0-4294967295</td>
<td>极大文本数据</td>
</tr>
</tbody></table>
<h4 id="5-2-3-日期类型"><a href="#5-2-3-日期类型" class="headerlink" title="5.2.3 日期类型"></a>5.2.3 日期类型</h4><table>
<thead>
<tr>
<th>类型</th>
<th>大小（Byte：字节）</th>
<th>范围</th>
<th>格式</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td><strong>date</strong></td>
<td>3</td>
<td>1000-01-01 至 9999-12-31</td>
<td>YYYY-MM-DD</td>
<td>日期值</td>
</tr>
<tr>
<td>time</td>
<td>3</td>
<td>-838:59:59 至 838:59:59</td>
<td>HH:MM:SS</td>
<td>时间值或持续时间</td>
</tr>
<tr>
<td>year</td>
<td>1</td>
<td>1901 至 2155</td>
<td>YYYY</td>
<td>年份值</td>
</tr>
<tr>
<td><strong>datetime</strong></td>
<td>8</td>
<td>1000-01-01 00:00:00 至  9999-12-31 23:59:59</td>
<td>YYYY-MM-DD HH:MM:SS</td>
<td>混合日期和时间值</td>
</tr>
<tr>
<td>timestamp</td>
<td>4</td>
<td>1970-01-01 00:00:01 至 2038-01-19 03:14:07</td>
<td>YYYY-MM-DD HH:MM:SS</td>
<td>混合日期和时间值，时间戳</td>
</tr>
</tbody></table>
<h3 id="5-3-DDL-数据定义语言"><a href="#5-3-DDL-数据定义语言" class="headerlink" title="5.3 DDL 数据定义语言"></a>5.3 DDL 数据定义语言</h3><p><strong>DDL</strong> （Data Definition Language，数据定义语言），用来定义数据库对象（数据库、表）。</p>
<h4 id="5-3-1-DDL中对数据库操作"><a href="#5-3-1-DDL中对数据库操作" class="headerlink" title="5.3.1 DDL中对数据库操作"></a>5.3.1 DDL中对数据库操作</h4><p>DDL对于数据库包含4个操作：</p>
<ul>
<li><p>查询</p>
<ul>
<li><p>查询所有数据库</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">show databases;<br></code></pre></td></tr></table></figure>
</li>
<li><p>查询当前数据库</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">select databases();<br></code></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>使用</p>
<ul>
<li><p>使用数据库</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">use 数据库名;<br></code></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>创建</p>
<ul>
<li><p>创建数据库</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">create database [if not exists] 数据库名;<br></code></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>删除</p>
<ul>
<li><p>删除数据库</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">drop database [if exists] 数据库名;<br></code></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>
<p><code>注：上述语法中的database，也可以替换成 schema，如：</code></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">create schema db01;<br></code></pre></td></tr></table></figure>

<h4 id="5-3-2-DDL-中对表操作"><a href="#5-3-2-DDL-中对表操作" class="headerlink" title="5.3.2 DDL 中对表操作"></a>5.3.2 DDL 中对表操作</h4><p>DDL中对表的操作主要有创建、查询、修改、删除。</p>
<p><strong>DDL 创建表</strong></p>
<p><code>注：SQL语句中带中括号的[]表示可选，可不加</code></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs mysql">create table 表名(<br>	字段1 字段类型 [约束] [comment 字段1注释],<br>    ......<br>    字段n 字段类型 [约束] [comment 字段n注释]<br>)[comment 表注释];<br></code></pre></td></tr></table></figure>

<p><strong>案例：DDL操作，创建一个用户表</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs mysql">create table tb_user(<br>	id int primary key comment &#x27;ID, 唯一标识&#x27;,<br>    username varchar(20) not null unique comment &#x27;用户名&#x27;,<br>    name varchar(10) not null comment &#x27;姓名&#x27;,<br>    age int comment &#x27;年龄&#x27;,<br>    gender char(1) default &#x27;男&#x27; comment &#x27;性别&#x27;<br>) comment &#x27;用户表&#x27;;<br></code></pre></td></tr></table></figure>

<h4 id="5-3-3-DDL-查询表"><a href="#5-3-3-DDL-查询表" class="headerlink" title="5.3.3 DDL 查询表"></a>5.3.3 DDL 查询表</h4><ul>
<li><p>查询当前数据库的所有表</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">show tables;<br></code></pre></td></tr></table></figure>
</li>
<li><p>查询表结构</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">desc 表名;<br></code></pre></td></tr></table></figure>
</li>
<li><p>查询建表语句</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">show create table 表名;<br></code></pre></td></tr></table></figure></li>
</ul>
<h4 id="5-3-4-DDL-修改表-和列"><a href="#5-3-4-DDL-修改表-和列" class="headerlink" title="5.3.4 DDL 修改表(和列)"></a>5.3.4 DDL 修改表(和列)</h4><ul>
<li><p>添加字段</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">alter table 表名 add 字段名 类型(长度) [comment 注释] [约束];<br></code></pre></td></tr></table></figure>
</li>
<li><p>修改字段类型</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">alter table 表名 modify 字段名 新数据类型(长度) [comment 注释];<br></code></pre></td></tr></table></figure>
</li>
<li><p>修改字段名和字段类型</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">alter table 表名 change 旧字段名 新字段名 类型(长度)[comment 注释] [约束];<br></code></pre></td></tr></table></figure>
</li>
<li><p>删除字段</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">alter table 表名 drop column 字段名;<br></code></pre></td></tr></table></figure>
</li>
<li><p>修改表名</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">rename table 表名 to 新表名;<br></code></pre></td></tr></table></figure></li>
</ul>
<p><strong>案例：DDL 修改表操作</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs mysql">-- DDL修改1: 为表 emp 添加字段 qq varchar(11)<br>alter table emp add qq varchar(11) comment &#x27;QQ&#x27;;<br><br>-- DDL修改2: 修改表 emp 字段类型 qq varchar(13)<br>alter table emp modify qq varchar(13) comment &#x27;QQ&#x27;;<br><br>-- DDL修改3: 修改 emp 字段名 qq 为 qq_num varchar(13)<br>alter table emp change qq qq_num varchar(13) comment &#x27;QQ&#x27;;<br><br>-- DDL修改4: 删除 emp 的 qq_num 字段<br>alter table emp drop column qq_num;<br><br>-- DDL修改5: 将 emp 表名修改为 emp_qq<br>rename table emp emp_qq;<br></code></pre></td></tr></table></figure>

<h4 id="5-3-5-DDL-删除表"><a href="#5-3-5-DDL-删除表" class="headerlink" title="5.3.5 DDL 删除表"></a>5.3.5 DDL 删除表</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">drop table [if exists] 表名;<br></code></pre></td></tr></table></figure>



<h3 id="5-4-DML-数据操作语言"><a href="#5-4-DML-数据操作语言" class="headerlink" title="5.4 DML 数据操作语言"></a>5.4 DML 数据操作语言</h3><p><strong>DML</strong>（Data Manipulation Language(数据操作语言)，用来对数据库中表的数据记录进行增、删、改操作。</p>
<h4 id="5-4-1-DML-INSERT"><a href="#5-4-1-DML-INSERT" class="headerlink" title="5.4.1 DML(INSERT)"></a>5.4.1 DML(INSERT)</h4><p><strong>MySQL insert 语法</strong></p>
<ul>
<li><p><strong>指定字段添加数据</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">insert into 表名(字段名1, 字段名2) values(值1, 值2);<br></code></pre></td></tr></table></figure>
</li>
<li><p><strong>全部字段添加数据</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">insert into 表名 values(值1, 值2, ...);<br></code></pre></td></tr></table></figure>
</li>
<li><p><strong>批量添加数据(指定字段)</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">insert into 表名(字段名1, 字段名2) values (值1, 值2),(值1, 值2);<br></code></pre></td></tr></table></figure>
</li>
<li><p><strong>批量添加数据(全部字段)</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">insert into 表名 values (值1, 值2, ...), (值1, 值2, ...);<br></code></pre></td></tr></table></figure></li>
</ul>
<p><strong>注意事项：</strong></p>
<ul>
<li>插入数据时，指定的字段顺序需要与值的顺序是一一对应的。</li>
<li>**字符串 **和 <strong>日期型</strong>数据应该包含在引号中。</li>
<li>插入的数据大小，应该在字段的规定范围内。</li>
</ul>
<h4 id="5-4-2-DML-UPDATE"><a href="#5-4-2-DML-UPDATE" class="headerlink" title="5.4.2 DML(UPDATE)"></a>5.4.2 DML(UPDATE)</h4><p><strong>DML update 语法</strong></p>
<p>修改表的数据：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">update 表名 set 字段名1=值1, 字段名2=值2, ... [where 条件];<br></code></pre></td></tr></table></figure>

<p><strong>注意事项：</strong></p>
<p>修改语句的条件可以有，也可以没有，若没有条件，则会修改整张表的所有数据。</p>
<h4 id="5-4-3-DML-DELETE"><a href="#5-4-3-DML-DELETE" class="headerlink" title="5.4.3 DML(DELETE)"></a>5.4.3 DML(DELETE)</h4><p>删除某(些)行数据：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">delete from 表名 [where 条件];<br></code></pre></td></tr></table></figure>

<p><strong>注意事项：</strong></p>
<ul>
<li>DELETE 语句的条件可以有，也可以没有，若没有条件，则会删除整张表的所有数据。</li>
<li>DELETE语句不能删除某一个字段的值(如果要操作，可以使用 UPDATE，将该字段的值设为NULL)。</li>
</ul>
<h3 id="5-5-DQL-数据查询语言"><a href="#5-5-DQL-数据查询语言" class="headerlink" title="5.5 DQL 数据查询语言"></a>5.5 DQL 数据查询语言</h3><p><strong>DQL（Data Query Language）数据查询语言</strong>，用来查询数据表中的记录。</p>
<p>关键字：&#96;&#96;SELECT&#96;</p>
<p><strong>DQL的查询语法：</strong></p>
<p><img src="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403121502441.png" srcset="/img/loading.gif" lazyload alt="image-20240312150257325"></p>
<h4 id="5-5-1-DQL-基本查询"><a href="#5-5-1-DQL-基本查询" class="headerlink" title="5.5.1 DQL 基本查询"></a>5.5.1 DQL 基本查询</h4><p><strong>DQL 基本查询的 语法：</strong></p>
<ul>
<li><p>查询多个字段</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT 字段1, 字段2, 字段3 FROM 表名;<br></code></pre></td></tr></table></figure>
</li>
<li><p>查询所有字段(通配符)</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT * FROM 表名;<br></code></pre></td></tr></table></figure>
</li>
<li><p>设置别名</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT 字段1 [AS 别名1], 字段2 [AS 别名2] FROM 表名;<br></code></pre></td></tr></table></figure>
</li>
<li><p>去除重复记录</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT DISTINCT 字段列表 FROM 表名;<br></code></pre></td></tr></table></figure></li>
</ul>
<h4 id="5-5-2-DQL-条件查询-WHERE"><a href="#5-5-2-DQL-条件查询-WHERE" class="headerlink" title="5.5.2 DQL 条件查询 WHERE"></a>5.5.2 DQL 条件查询 WHERE</h4><p><strong>DQL 条件查询 语句：</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT 字段列表 FROM 表名 WHERE 条件列表;<br></code></pre></td></tr></table></figure>

<table>
<thead>
<tr>
<th>比较运算符</th>
<th>功能</th>
</tr>
</thead>
<tbody><tr>
<td>&gt;</td>
<td>大于</td>
</tr>
<tr>
<td>&gt;&#x3D;</td>
<td>大于或等于</td>
</tr>
<tr>
<td>&lt;</td>
<td>小于</td>
</tr>
<tr>
<td>&lt;&#x3D;</td>
<td>小于或等于</td>
</tr>
<tr>
<td>&#x3D;</td>
<td>等于</td>
</tr>
<tr>
<td>&lt;&gt; 或 !&#x3D;</td>
<td>不等于</td>
</tr>
<tr>
<td>between … and …</td>
<td>在某个范围之内(含最小值和最大值)</td>
</tr>
<tr>
<td>in (…)</td>
<td>在 in 之后的列表中的值，多选一</td>
</tr>
<tr>
<td>like 占位符</td>
<td>模糊匹配 (<code>_</code> 匹配单个字符，<code>%</code> 匹配任意个字符)</td>
</tr>
<tr>
<td>is null</td>
<td>判断是 null</td>
</tr>
</tbody></table>
<table>
<thead>
<tr>
<th>逻辑运算符</th>
<th>功能</th>
</tr>
</thead>
<tbody><tr>
<td>and 或 &amp;&amp;</td>
<td>并且（多个条件同时成立）</td>
</tr>
<tr>
<td>or 或 ||</td>
<td>或者（多个条件任意一个成立）</td>
</tr>
<tr>
<td>not 或 |</td>
<td>非，不是</td>
</tr>
</tbody></table>
<h4 id="5-5-3-DQL-分组查询-GROUP-BY"><a href="#5-5-3-DQL-分组查询-GROUP-BY" class="headerlink" title="5.5.3 DQL 分组查询 GROUP BY"></a>5.5.3 DQL 分组查询 GROUP BY</h4><p>DQL 分组查询操作会用到 聚合函数。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs mysql">-- 聚合函数是指将一列数据作为一个整体，进行纵向计算。<br><br>-- 聚合函数的语法:<br><br>SELECT 聚合函数(字段列表) FROM 表名;<br></code></pre></td></tr></table></figure>

<p><strong>常用聚合函数：</strong></p>
<table>
<thead>
<tr>
<th>函数</th>
<th>功能</th>
</tr>
</thead>
<tbody><tr>
<td>count</td>
<td>统计数量</td>
</tr>
<tr>
<td>max</td>
<td>最大值</td>
</tr>
<tr>
<td>min</td>
<td>最小值</td>
</tr>
<tr>
<td>avg</td>
<td>平均值</td>
</tr>
<tr>
<td>sum</td>
<td>求和</td>
</tr>
</tbody></table>
<p><strong>注意事项：</strong></p>
<ul>
<li>null 值不参与所有聚合函数运算。</li>
<li>统计数量可以使用：<code>count(*)</code>、<code>count(字段)</code>、<code>count(常量)</code>，推荐使用<code>count(*)</code>。</li>
</ul>
<p><strong>DQL 分组查询</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT 字段列表 FROM 表名 [where 条件] GROUP BY 分组字段名 [HAVING 分组后过滤条件];<br></code></pre></td></tr></table></figure>

<p><strong>例1：统计不同性别的员工数量</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT gender, count(*) FROM emp GROUP BY gender;<br></code></pre></td></tr></table></figure>

<p><strong>例2：先查询入职时间在2015-01-01(包含)以前的员工，并对结果根据职位分组，获取员工数量大于等于2的职位</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT job, count(*) <br>	FROM emp <br>	WHERE entrydate &gt;= &#x27;2015-01-01&#x27; <br>GROUP BY JOB<br>HAVING count(*) &gt;= 2;    <br></code></pre></td></tr></table></figure>

<p><strong><code>where</code> 与 <code>having</code> 的区别：</strong></p>
<ol>
<li><strong>执行时机不同：</strong>where 是分组之前进行过滤，不满足 where 条件，不参与分组，而 having 是分组之后对结果进行过滤。</li>
<li><strong>判断条件不同：</strong>where不能对聚合函数进行判断，而 having 可以。</li>
</ol>
<p><strong>注意事项：</strong></p>
<ul>
<li>分组之后，查询的字段一般为聚合函数和分组字段，查询其他字段没有意义。</li>
<li><strong>执行顺序：</strong>where &gt; 聚合函数 &gt; having。</li>
</ul>
<h4 id="5-5-4-排序查询-ORDER-BY"><a href="#5-5-4-排序查询-ORDER-BY" class="headerlink" title="5.5.4 排序查询 ORDER BY"></a>5.5.4 排序查询 ORDER BY</h4><p>通常在条件查询后使用排序查询。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT 字段列表 FROM 表名 [WHERE 条件列表]<br>[GROUP BY 分组字段]<br>ORDER BY 字段1 排序方式1, 字段2 排序方式2 ...;<br></code></pre></td></tr></table></figure>

<p>排序方式一共有两种：</p>
<ul>
<li><strong>ASC：升序（默认值）</strong></li>
<li><strong>DESC：降序</strong></li>
</ul>
<p><strong>注意事项：</strong> 若是多字段排序，当第一个字段值相同时，才会根据第二个字段进行排序。</p>
<h4 id="5-5-5-分页查询-LIMIT"><a href="#5-5-5-分页查询-LIMIT" class="headerlink" title="5.5.5 分页查询 LIMIT"></a>5.5.5 分页查询 LIMIT</h4><p>分页查询语法：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT 字段列表 FROM 表名 LIMIT 起始索引,查询记录数;<br></code></pre></td></tr></table></figure>



<p><strong>例1：从起始索引0开始查询员工数据，每页展示5条记录</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT * FROM emp LIMIT 0, 5;<br></code></pre></td></tr></table></figure>

<p><strong>例2：查询 第1页 员工数据，每页展示5条记录</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT * FROM emp LIMIT 0, 5;<br></code></pre></td></tr></table></figure>

<p><strong>例3：查询 第2页 员工数据，每页展示5条记录</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT * FROM emp LIMIT 5, 5;<br></code></pre></td></tr></table></figure>

<p><strong>注意事项</strong></p>
<ul>
<li><code>LIMIT</code> 的起始索引从0开始，起始索引 &#x3D; (查询页码 -1) * 每页显示记录数。</li>
<li>分页查询是数据库的方言，不同的数据库有不同的实现，MySQL是 LIMIT。</li>
<li>如果查询的是第一页数据，起始索引可以省略，直接简写为 LIMIT 10。</li>
</ul>
<h4 id="5-5-6-DQL-案例"><a href="#5-5-6-DQL-案例" class="headerlink" title="5.5.6 DQL 案例"></a>5.5.6 DQL 案例</h4><p><strong>案例1：</strong>统计员工的性别人数，并将值改为男性员工和女性员工这两种。</p>
<p>为实现上述案例，需要用到 MySQL 支持的条件语句：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">if(条件表达式, true取值, false取值)<br></code></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT IF(gender=1, &#x27;男性员工&#x27;, &#x27;女性员工&#x27;) 性别, COUNT(*) FROM temp<br>GROUP BY gender;<br></code></pre></td></tr></table></figure>

<p><strong>案例2：</strong>完成员工职位信息的统计，统计不同职位的人数，且区分不同的职位。</p>
<p>为实现上述案例，需用到 MySQL 支持的 CASE 语句：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs mysql">CASE 表达式 <br>WHEN 值1 THEN 结果1 <br>WHEN 值2 THEN 结果2<br>...<br>ELSE<br>...<br>END<br></code></pre></td></tr></table></figure>



<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT <br>	(CASE job WHEN 1 THEN &#x27;班主任&#x27;<br>     WHEN 2 THEN &#x27;讲师&#x27;<br>     WHEN 3 THEN &#x27;学工主管&#x27;<br>     WHEN 4 THEN &#x27;教研主管&#x27;<br>     ELSE &#x27;未分配职位&#x27;<br>     END)<br><br>, COUNT(*) <br>FROM emp <br>GROUP BY job;<br></code></pre></td></tr></table></figure>



<p>总结 DQL 分页查询中会用到的MySQL的函数：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs mysql">IF (表达式, tvalue, fvalue)<br>-- 当表达式为 true 时, 取值为 tvalue<br>-- 当表达式为 false 时，取值为 fvalue<br><br>CASE expr WHEN value1 THEN result1<br>[WHEN value2 THEN value2 ...]<br>[ELSE RESULT]<br>END<br></code></pre></td></tr></table></figure>



<h2 id="6、MySQL-多表设计"><a href="#6、MySQL-多表设计" class="headerlink" title="6、MySQL 多表设计"></a>6、MySQL 多表设计</h2><h3 id="6-1-多表设计概述"><a href="#6-1-多表设计概述" class="headerlink" title="6.1 多表设计概述"></a>6.1 多表设计概述</h3><p>项目开发中，在进行数据库表结构设计时，会根据<strong>业务需求及业务模块之间的关系</strong>，分析并设计表结构，由于业务之间相互关联，所以各个表结构之间也存在着联系，基本上分为三种：</p>
<ul>
<li>一对多、多对一</li>
<li>多对多</li>
<li>一对一</li>
</ul>
<p>为方便学习，接下来设计一个部门相关的数据表</p>
<p>建表语句如下：</p>
<h3 id="6-2-一对多的关系实现"><a href="#6-2-一对多的关系实现" class="headerlink" title="6.2 一对多的关系实现"></a>6.2 一对多的关系实现</h3><p><strong>案例：</strong>建立员工和部门表，一个员工最多归属于一个部门。</p>
<p><strong>员工表</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs mysql">CREATE TABLE tb_emp(<br>	id int unsigned primary key auto_increment comment &#x27;ID&#x27;,<br>    username varchar(20) not null unique comment &#x27;用户名&#x27;,<br>    password varchar(32) default &#x27;123456&#x27; comment &#x27;密码&#x27;,<br>    name varchar(10) not null comment &#x27;姓名&#x27;,<br>    gender tinyint unsigned not null comment &#x27;性别, 说明: 1 男, 2 女&#x27;,<br>    image varchar(300) comment &#x27;图像&#x27;,<br>    job tinyint unsigned comment &#x27;职位, 说明: 1 班主任 2讲师 3 学工主管 4 教研主管&#x27;,<br>    entrydate date comment &#x27;入职时间&#x27;,<br>    dept_id unsigned comment &#x27;归属的部门ID&#x27;,<br>    create_time datetime not null comment &#x27;创建时间&#x27;,<br>    update_time datetime not null comment &#x27;修改时间&#x27;<br>) COMMENT &#x27;员工表&#x27;;<br></code></pre></td></tr></table></figure>

<p><strong>部门表</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs mysql">CREATE TABLE tb_dept(<br>	id int unsigned primary key auto_increment comment &#x27;ID&#x27;,<br>    name varchar(10) not null unique comment &#x27;部门名称&#x27;,<br>    create_time datetime not null comment &#x27;创建时间&#x27;,<br>    update_time datetime not null comment &#x27;修改时间&#x27;<br>) COMMENT &#x27;部门表&#x27;,<br></code></pre></td></tr></table></figure>

<p>一个员工属于一个部门，而一个部门会有多个员工。</p>
<p>故员工与部门是多对一的关系，其中部门是父表，员工是子表。</p>
<p><strong>一对多的关系实现：</strong>在数据库表中多的一方添加字段来关联一的一方的主键。</p>
<h3 id="6-3-MySQL-外键约束"><a href="#6-3-MySQL-外键约束" class="headerlink" title="6.3 MySQL 外键约束"></a>6.3 MySQL 外键约束</h3><p><strong>多表问题的现象于分析</strong>（基于上面的案例）</p>
<p><strong>现象：</strong>在上述建表语句中，员工表里有部门的ID，不过部门数据可以直接删除，若此时还有员工归属于该部门下，则会出现数据的不完整、不一致的问题。</p>
<p><strong>问题分析：</strong> 目前上述的两张表，在数据库层面，并未建立关联，所以是无法保证数据的一致性和完整性的。</p>
<p>这种情况下，需要用外键约束来解决问题。</p>
<p>外键约束的语法如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs mysql">-- 方式1: 在创建表时指定外键<br>CREATE TBLE 表名(<br>	字段名 数据类型,<br>    ...<br>    [CONSTRAINT] [外键名称] FOREIGN KEY (外键字段名)<br>    REFERENCES 主表(字段名)<br>);<br><br>-- 方式2: 表建完后, 添加外键<br>ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERENCES 主表(字段名);<br></code></pre></td></tr></table></figure>



<h4 id="6-3-1-物理外键"><a href="#6-3-1-物理外键" class="headerlink" title="6.3.1 物理外键"></a>6.3.1 物理外键</h4><p><strong>概念：</strong>使用 <code>FOREIGN KEY</code> 定义外键关联另外一张表。</p>
<p><strong>缺点：</strong></p>
<ul>
<li>影响增、删、改的效率（需要检查外键关系）。</li>
<li>仅用于单节点数据库，不适用于分布式、集群场景。</li>
<li>容易引发数据库的死锁问题，消耗性能。</li>
</ul>
<h4 id="6-3-2-逻辑外键"><a href="#6-3-2-逻辑外键" class="headerlink" title="6.3.2 逻辑外键"></a>6.3.2 逻辑外键</h4><p><strong>概念：</strong>在业务逻辑中，解决外键关联。</p>
<p>通过逻辑外键，就可以很方便得解决上述问题。</p>
<h3 id="6-4-一对一的关系实现"><a href="#6-4-一对一的关系实现" class="headerlink" title="6.4 一对一的关系实现"></a>6.4 一对一的关系实现</h3><p><strong>案例：</strong> 用户与身份证信息的关系</p>
<p><strong>关系：</strong>一个用户只有一张身份证，一张身份证只对应于一个人，故用户与身份证信息是一对一关系，这种关系多用于单表拆分，将一张表的基础字段放在一张表中，其他字段放在另一张表中欧，以提升操作效率。</p>
<p><strong>实现：</strong> 在任意一方加入外键，关联另外一方的主键，并且设置外键为唯一的 （UNIQUE）。</p>
<p><strong>用户表：</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs mysql">CREATE TABLE tb_user(<br>	id int unsigned primary key auto_increment comment &#x27;ID&#x27;,<br>    name varchar(10) not null comment &#x27;姓名&#x27;,<br>    gender tinyint unsigned not null comment &#x27;性别, 1 男 2 女&#x27;,<br>    phone char(11) comment &#x27;手机号&#x27;,<br>    degree varchar(10) comment &#x27;学历&#x27;,<br>) COMMENT &#x27;用户信息表&#x27;;<br></code></pre></td></tr></table></figure>

<p><strong>用户信息表：</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs mysql">CREATE TABLE tb_user_card(<br>	id int unsigned primary key auto_increment comment &#x27;ID&#x27;,<br>    nationality varchar(10) not null comment &#x27;民族&#x27;,<br>    birthday date not null comment &#x27;生日&#x27;,<br>    idcard char(18) not null comment &#x27;身份证号&#x27;,<br>    issued varchar(20) not null comment &#x27;签发机关&#x27;,<br>    expire_begin date not null comment &#x27;有效期限-开始&#x27;,<br>    expire_end date comment &#x27;有效期限-结束&#x27;,<br>    user_id int unsigned not null unique comment &#x27;用户ID&#x27;,<br>    constraint fk_user_id foreign key (user_id) references tb_user(id)<br>)COMMENT &#x27;用户信息表&#x27;;<br></code></pre></td></tr></table></figure>



<p>上述例子中，为实现一对一，在用户信息表中添加了唯一的外键 <code>user_id</code>。</p>
<h3 id="6-5-多对多的关系实现"><a href="#6-5-多对多的关系实现" class="headerlink" title="6.5 多对多的关系实现"></a>6.5 多对多的关系实现</h3><p><strong>案例：</strong>学生与课程的关系</p>
<p><strong>关系：</strong>一个学生可选修多门课程，一门课程也可以供多个学生选择。</p>
<p><strong>实现：</strong> 建立第三张<strong>中间表</strong>，中间表至少包含<strong>两个</strong>外键，分别关联两方<strong>主键</strong>。</p>
<p><img src="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403121752385.png" srcset="/img/loading.gif" lazyload alt="image-20240312175227246"></p>
<p>学生表</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs mysql">CREATE TABLE tb_student(<br>	id int auto_increment primary key comment &#x27;主键ID&#x27;,<br>    name varchar(10) comment &#x27;姓名&#x27;,<br>    no varchar(10) comment &#x27;学号&#x27;<br>) COMMENT &#x27;学生表&#x27;;<br></code></pre></td></tr></table></figure>

<p>课程表</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs mysql">CREATE TABLE tb_course(<br>	id int auto_increment primary key comment &#x27;主键ID&#x27;,<br>    name varchar(10) comment &#x27;课程名称&#x27;<br>)COMMENT &#x27;课程表&#x27;;<br></code></pre></td></tr></table></figure>

<p>学生课程中间表</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs mysql">CREATE TABLE tb_student_course(<br>	id int auto_increment comment &#x27;主键&#x27; primary key,<br>    student_id int not null comment &#x27;学生ID&#x27;,<br>    course_id int not null comment &#x27;课程ID&#x27;,<br>    constraint fk_courseId foreign key(course_id) references tb_course(id),<br>    constraint fk_studentId foreign key(student_id) tb_student (id)<br>) COMMENT &#x27;学生课程中间表&#x27;;<br></code></pre></td></tr></table></figure>

<p><strong>总结：</strong></p>
<ul>
<li><strong>一对多：</strong>在多的一方添加外键，关联另外一方的主键。</li>
<li><strong>一对一：</strong>任意一方，添加外键，关联另外一方的主键。</li>
<li><strong>多对多：</strong>通过中间表来维护，中间表的两个外键，分别关联另外两张表的主键。</li>
</ul>
<h2 id="7、多表查询"><a href="#7、多表查询" class="headerlink" title="7、多表查询"></a>7、多表查询</h2><p><strong>案例：</strong>员工和部门是多对多的关系</p>
<p>部门表</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs mysql">CREATE TABLE tb_dept(<br>	id int unsigned primary key auto_increment comment &#x27;主键ID&#x27;,<br>    name varchar(10) not null unique comment &#x27;部门名称&#x27;,<br>    create_time datetime not null comment &#x27;创建时间&#x27;,<br>    update_time datetime not null comment &#x27;修改时间&#x27;<br>) COMMENT &#x27;部门表&#x27;;<br></code></pre></td></tr></table></figure>

<p>职位表</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs mysql">CREATE TABLE tb_emp(<br>	id int unsigned primary key auto_increment comment &#x27;ID&#x27;,<br>    username varchar(20) not null unique comment &#x27;用户名&#x27;,<br>    password varchar(32) default &#x27;123456&#x27; comment &#x27;密码&#x27;,<br>    name varchar(10) not null comment &#x27;姓名&#x27;,<br>    gender tinyint unsigned not null comment &#x27;性别, 说明: 1 男, 2 女&#x27;,<br>    image varchar(300) comment &#x27;图像&#x27;,<br>    job tinyint unsigned comment &#x27;职位, 说明: 1班主任, 2讲师, 3学工主管, 4教研主管, 5咨询师&#x27;,<br>    entrydate date comment &#x27;入职时间&#x27;,<br>    dept_id int unsigned comment &#x27;部门ID&#x27;,<br>    create_time datetime not null comment &#x27;创建时间&#x27;,<br>    update_time datetime not null comment &#x27;修改时间&#x27;	<br>) COMMENT &#x27;员工表&#x27;;<br></code></pre></td></tr></table></figure>



<p>接下来插入一些模拟数据，注意下列数据中有空部门后勤部，和不属于任何部门的陈七：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs mysql">INSERT INTO tb_dept (name, create_time, update_time)<br>VALUES<br>(&#x27;技术部&#x27;, &#x27;2024-03-06 09:00:00&#x27;, &#x27;2024-03-06 09:00:00&#x27;),<br>(&#x27;人事部&#x27;, &#x27;2024-03-06 09:00:00&#x27;, &#x27;2024-03-06 09:00:00&#x27;),<br>(&#x27;财务部&#x27;, &#x27;2024-03-06 09:00:00&#x27;, &#x27;2024-03-06 09:00:00&#x27;),<br>(&#x27;市场部&#x27;, &#x27;2024-03-06 09:00:00&#x27;, &#x27;2024-03-06 09:00:00&#x27;),<br>(&#x27;后勤部&#x27;, &#x27;2024-03-06 09:00:00&#x27;, &#x27;2024-03-06 09:00:00&#x27;)<br>;<br><br>INSERT INTO tb_emp (username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time)<br>VALUES<br>(&#x27;user1&#x27;, &#x27;123456&#x27;, &#x27;张三&#x27;, 1, &#x27;/images/user1.jpg&#x27;, 1, &#x27;2022-01-01&#x27;, 1, &#x27;2024-03-06 09:00:00&#x27;, &#x27;2024-03-06 09:00:00&#x27;),<br>(&#x27;user2&#x27;, &#x27;123456&#x27;, &#x27;李四&#x27;, 1, &#x27;/images/user2.jpg&#x27;, 2, &#x27;2022-01-01&#x27;, 2, &#x27;2024-03-06 09:00:00&#x27;, &#x27;2024-03-06 09:00:00&#x27;),<br>(&#x27;user3&#x27;, &#x27;123456&#x27;, &#x27;王五&#x27;, 2, &#x27;/images/user3.jpg&#x27;, 3, &#x27;2022-01-01&#x27;, 3, &#x27;2024-03-06 09:00:00&#x27;, &#x27;2024-03-06 09:00:00&#x27;),<br>(&#x27;user4&#x27;, &#x27;123456&#x27;, &#x27;赵六&#x27;, 1, &#x27;/images/user4.jpg&#x27;, 4, &#x27;2022-01-01&#x27;, 4, &#x27;2024-03-06 09:00:00&#x27;, &#x27;2024-03-06 09:00:00&#x27;),<br>(&#x27;user5&#x27;, &#x27;123456&#x27;, &#x27;陈七&#x27;, 1, &#x27;/images/user4.jpg&#x27;, 4, &#x27;2022-01-01&#x27;, 0, &#x27;2024-03-06 09:00:00&#x27;, &#x27;2024-03-06 09:00:00&#x27;);<br></code></pre></td></tr></table></figure>



<p>多表查询是指从多张表中查询数据，如：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT * FROM tb_emp, tb_dept;<br></code></pre></td></tr></table></figure>



<p><strong>笛卡尔积：</strong>笛卡尔积成绩是指在数学中，两个集合（A集合 和 B集合）的所有组合情况。（在多表查询时，需要消除无效的笛卡尔积）。</p>
<p><img src="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403122010618.png" srcset="/img/loading.gif" lazyload alt="image-20240312201037385"></p>
<p>多表查询分类有两种：</p>
<ul>
<li>连接查询<ul>
<li>内连接：用于查询A、B交集的部分数据</li>
<li>外连接：<ul>
<li>左外连接：查询 <strong>左表</strong> 所有数据（包含两张表交集部分数据）</li>
<li>右外连接：查询 <strong>右表</strong> 所有数据（包含两张表交集部分数据）</li>
</ul>
</li>
</ul>
</li>
<li>子查询</li>
</ul>
<h3 id="7-1-内连接"><a href="#7-1-内连接" class="headerlink" title="7.1 内连接"></a>7.1 内连接</h3><p><img src="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403130228111.png" srcset="/img/loading.gif" lazyload alt="image-20240313022817912"></p>
<p>语法</p>
<ul>
<li>隐式内连接</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT 字段列表 FROM 表1, 表2 WHERE 条件...;<br></code></pre></td></tr></table></figure>

<ul>
<li>显式内连接</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 连接条件...; <br></code></pre></td></tr></table></figure>

<p><strong>案例：</strong>使用隐式和显式两种不同的方式实现查询员工的性能，关联所属的部门名称。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs mysql">-- 隐式内连接<br>select tb_emp.name as 名字, tb_dept.name as 所属部门 from tb_emp, tb_dept where tb_emp.dept_id = tb_dept.id;<br><br><br>-- 显式内连接<br>select tb_emp.name as 名字, tb_dept.name as 所属部门 from tb_emp inner join tb_dept on tb_emp.dept_id = tb_dept.id;<br></code></pre></td></tr></table></figure>

<p>执行结果：</p>
<figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs asciidoc"><span class="hljs-code">+------+</span>----------+<br><span class="hljs-section">| 名字 | 所属部门 |</span><br><span class="hljs-section">+------+----------+</span><br>| 张三 | 技术部   |<br>| 李四 | 人事部   |<br>| 王五 | 财务部   |<br><span class="hljs-section">| 赵六 | 市场部   |</span><br><span class="hljs-section">+------+----------+</span><br></code></pre></td></tr></table></figure>

<p>对于上面的语句，可以优化一下，比如在设置表名时，给表起别名</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">select emp.name as 名字, dept.name as 部门 from tb_emp as emp inner join tb_dept as dept on emp.dept_id = dept.id;<br></code></pre></td></tr></table></figure>

<h3 id="7-2-外连接"><a href="#7-2-外连接" class="headerlink" title="7.2 外连接"></a>7.2 外连接</h3><p><img src="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403130228551.png" srcset="/img/loading.gif" lazyload alt="image-20240313022858405"></p>
<p>语法：</p>
<ul>
<li>左外连接</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT 字段列表 FROM 表1 LEFT [OTHER] JOIN 表2 ON 连接条件 ...;<br></code></pre></td></tr></table></figure>

<ul>
<li>右外连接</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT 字段列表 FROM 表1 RIGHT [OTHER] JOIN 表2 ON 连接条件 ...;<br></code></pre></td></tr></table></figure>

<p><strong>案例：</strong>使用两种外连接方式查询员工表所有员工的姓名和对应的部门。</p>
<p>员工表左外连接部门表</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs mysql">-- 左外连接<br>select emp.name as 名字, dept.name as 所属部门 from tb_emp emp left join tb_dept dept on emp.dept_id = dept.id;<br></code></pre></td></tr></table></figure>

<p>执行结果：</p>
<figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs asciidoc"><span class="hljs-code">+------+</span>----------+<br><span class="hljs-section">| 名字 | 所属部门 |</span><br><span class="hljs-section">+------+----------+</span><br>| 张三 | 技术部   |<br>| 李四 | 人事部   |<br>| 王五 | 财务部   |<br>| 赵六 | 市场部   |<br><span class="hljs-section">| 陈七 | NULL     |</span><br><span class="hljs-section">+------+----------+</span><br></code></pre></td></tr></table></figure>

<p>员工表右外连接部门表</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">select emp.name as 名字, dept.name as 所属部门 from  tb_emp emp right join tb_dept dept on dept.id = emp.dept_id;<br></code></pre></td></tr></table></figure>

<p>执行结果：</p>
<figure class="highlight gherkin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs gherkin">+------+----------+<br>|<span class="hljs-string"> 名字 </span>|<span class="hljs-string"> 所属部门 </span>|<br>+------+----------+<br>|<span class="hljs-string"> 张三 </span>|<span class="hljs-string"> 技术部   </span>|<br>|<span class="hljs-string"> 李四 </span>|<span class="hljs-string"> 人事部   </span>|<br>|<span class="hljs-string"> 王五 </span>|<span class="hljs-string"> 财务部   </span>|<br>|<span class="hljs-string"> 赵六 </span>|<span class="hljs-string"> 市场部   </span>|<br>|<span class="hljs-string"> NULL </span>|<span class="hljs-string"> 后勤部   </span>|<br></code></pre></td></tr></table></figure>

<p>可以看到左右连接的查询结果不同</p>
<h3 id="7-3-子查询"><a href="#7-3-子查询" class="headerlink" title="7.3 子查询"></a>7.3 子查询</h3><p>SQL语句中嵌套 SELECT 语句，称为嵌套查询，又称子查询。</p>
<p>语法：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT * <br>FROM t1 <br>WHERE column1 = (SELECT column1 FROM t2);<br></code></pre></td></tr></table></figure>

<p>子查询外部的语句可以是 INSERT &#x2F; UPDATE &#x2F; DELETE &#x2F; SELECT 中的任何一个，这意味着子查询同时包含 DML操作 和 DQL操作，最常见的是 DQL的SELECT操作。</p>
<p>子查询一共有4种分类：</p>
<ul>
<li>标量子查询: 子查询返回的结果为单个值</li>
<li>列子查询：子查询返回的结果为一列</li>
<li>行子查询：子查询返回的结果为一行</li>
<li>表子查询：子查询返回的结果为多行多列</li>
</ul>
<h4 id="7-3-1-标量子查询"><a href="#7-3-1-标量子查询" class="headerlink" title="7.3.1 标量子查询"></a>7.3.1 标量子查询</h4><p>子查询返回的结果是单个值(数字、字符串、日期等)，最简单的形式。</p>
<p>常见的操作符：<code>=</code>，<code>&lt;&gt;</code>，<code>&gt;</code>，<code>&gt;=</code>，<code>&lt;</code>，<code>&lt;=</code></p>
<p><strong>案例1：</strong>查询 “技术部” 的所有员工信息</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs mysql">-- 第1步 查询 教研部 的部门ID - tb_dept<br>SELECT id FROM tb_dept where name = &#x27;技术部&#x27;;<br></code></pre></td></tr></table></figure>

<p>查询结果：</p>
<figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs asciidoc"><span class="hljs-code">+----+</span><br><span class="hljs-section">| id |</span><br><span class="hljs-section">+----+</span><br><span class="hljs-section">|  1 |</span><br><span class="hljs-section">+----+</span><br></code></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs mysql">-- 第2步 查询该部门ID下的员工信息 - tb_emp<br>SELECT name FROM tb_emp where dept_id = 1;<br></code></pre></td></tr></table></figure>

<p>查询结果：</p>
<figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs asciidoc"><span class="hljs-code">+-------+</span><br><span class="hljs-section">| name |</span><br><span class="hljs-section">+-------+</span><br><span class="hljs-section">| 张三  |</span><br><span class="hljs-section">+-------+</span><br></code></pre></td></tr></table></figure>

<p>将上面的两个查询合并成一个子查询。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">select name from tb_emp where dept_id = (select id from tb_dept where name = &#x27;技术部&#x27;);<br></code></pre></td></tr></table></figure>

<p><strong>案例2：</strong> 查询在 “张三” 入职后的员工信息</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs mysql">-- 第1步 查询张三的入职时间<br>SELECT entrydate from tb_emp where name = &#x27;张三&#x27;;<br></code></pre></td></tr></table></figure>

<p>查询结果：</p>
<figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs asciidoc"><span class="hljs-code">+------------+</span><br><span class="hljs-section">| entrydate   |</span><br><span class="hljs-section">+------------+</span><br><span class="hljs-section">| 2022-01-01 |</span><br><span class="hljs-section">+------------+</span><br></code></pre></td></tr></table></figure>



<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs mysql">-- 第2步 查询在 2022-01-01 后入职的员工<br>SELECT name FROM tb_emp WHERE entrydate &gt; &#x27;2022-01-01&#x27;;<br></code></pre></td></tr></table></figure>

<p>查询结果：</p>
<figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs asciidoc"><span class="hljs-code">+-------+</span><br><span class="hljs-section">| name |</span><br><span class="hljs-section">+-------+</span><br><span class="hljs-section">| 陈七  |</span><br><span class="hljs-section">+-------+</span><br></code></pre></td></tr></table></figure>

<p>合并上面的两步查询语句后的标量子查询为：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT name FROM tb_emp WHERE entrydate &gt; (SELECT entrydate FROM tb_emp WHERE name = &#x27;张三&#x27;);<br></code></pre></td></tr></table></figure>

<h4 id="7-3-2-列子查询"><a href="#7-3-2-列子查询" class="headerlink" title="7.3.2 列子查询"></a>7.3.2 列子查询</h4><p>列子查询是指返回一列（<strong>可以是多行</strong>）结果的子查询</p>
<p>常用操作符：<code>in</code>，<code>not in</code>等。</p>
<p><strong>案例：</strong>查询”人事部”和”技术部”所有员工名字和所属部门名称</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs mysql">-- 第1步 查询 人事部 和 技术部 的部门ID<br>SELECT id FROM tb_dept WHERE name = &#x27;人事部&#x27; OR name = &#x27;技术部&#x27;;<br></code></pre></td></tr></table></figure>

<p>查询结果</p>
<figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs asciidoc"><span class="hljs-code">+----+</span><br><span class="hljs-section">| id |</span><br><span class="hljs-section">+----+</span><br>|  2 |<br><span class="hljs-section">|  1 |</span><br><span class="hljs-section">+----+</span><br></code></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs mysql">-- 第2步 根据部门ID查询员工信息<br>SELECT name FROM tb_emp WHERE dept_id IN (1,2);<br></code></pre></td></tr></table></figure>

<p>查询结果</p>
<figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs asciidoc"><span class="hljs-code">+-------+</span><br><span class="hljs-section">| name |</span><br><span class="hljs-section">+-------+</span><br>| 张三  |<br><span class="hljs-section">| 李四  |</span><br><span class="hljs-section">+-------+</span><br></code></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs mysql">-- 第3步 用左连接查询，补充员工的部门名称<br>SELECT emp.name 名字, dept.name 所属部门 FROM tb_emp emp LEFT JOIN tb_dept dept<br>ON emp.dept_id = dept.id<br>WHERE emp.name IN (&#x27;张三&#x27;, &#x27;李四&#x27;);<br></code></pre></td></tr></table></figure>

<p>查询结果</p>
<figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs asciidoc"><span class="hljs-code">+------+</span>----------+<br><span class="hljs-section">| 名字 | 所属部门 |</span><br><span class="hljs-section">+------+----------+</span><br>| 张三 | 技术部   |<br><span class="hljs-section">| 李四 | 人事部   |</span><br><span class="hljs-section">+------+----------+</span><br></code></pre></td></tr></table></figure>

<p>合并上面三步，最终用列子查询实现</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT emp.name AS 名字,<br>	(SELECT dept.name FROM tb_dept dept WHERE dept.id = emp.dept_id) AS 所属部门<br>FROM tb_emp emp<br>WHERE emp.dept_id IN (SELECT id FROM tb_dept WHERE name IN (&#x27;人事部&#x27;, &#x27;技术部&#x27;));<br></code></pre></td></tr></table></figure>

<p>查询结果：</p>
<figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs asciidoc"><span class="hljs-code">+------+</span>----------+<br><span class="hljs-section">| 名字 | 所属部门 |</span><br><span class="hljs-section">+------+----------+</span><br>| 张三 | 技术部   |<br><span class="hljs-section">| 李四 | 人事部   |</span><br><span class="hljs-section">+------+----------+</span><br></code></pre></td></tr></table></figure>



<p>当然这个需求直接用左连接更容易</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT emp.name 名字, dept.name 所属部门<br>FROM tb_emp emp LEFT JOIN tb_dept dept<br>ON emp.dept_id = dept.id<br>WHERE dept.name IN (&#x27;技术部&#x27;, &#x27;人事部&#x27;);<br></code></pre></td></tr></table></figure>

<h4 id="7-3-3-行子查询"><a href="#7-3-3-行子查询" class="headerlink" title="7.3.3 行子查询"></a>7.3.3 行子查询</h4><p>行子查询是指返回的结果是一行（可以是多列）。</p>
<p>常用的操作符：<code>=</code>、<code>&lt;&gt;</code>、<code>in</code>、<code>not in</code></p>
<p><strong>案例：</strong> 查询与”张三” 的入职日期及职位都相同的员工信息。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs mysql">-- 第1步, 查询张三的入职日期和职位<br>SELECT entrydate, job<br>FROM tb_emp<br>WHERE name = &#x27;张三&#x27;;<br></code></pre></td></tr></table></figure>

<p>查询结果</p>
<figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs asciidoc"><span class="hljs-code">+------------+</span>-----+<br><span class="hljs-section">| entrydate   | job |</span><br><span class="hljs-section">+------------+-----+</span><br><span class="hljs-section">| 2022-01-01 |   1 |</span><br><span class="hljs-section">+------------+-----+</span><br></code></pre></td></tr></table></figure>



<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs mysql">-- 第2步, 查询和张三入职日期和职位都相同的员工名称<br>SELECT name <br>FROM tb_emp emp<br>WHERE entrydate = &#x27;2022-01-01&#x27; AND job = 1;<br></code></pre></td></tr></table></figure>

<p>查询结果</p>
<figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs asciidoc"><span class="hljs-code">+-------+</span><br><span class="hljs-section">| name |</span><br><span class="hljs-section">+-------+</span><br><span class="hljs-section">| 张三  |</span><br><span class="hljs-section">+-------+</span><br></code></pre></td></tr></table></figure>

<p>由于模拟的数据比较少，所以这个情况只有张三一人</p>
<p>合并上面的两步查询</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT name FROM tb_emp emp WHERE (entrydate, job) = (SELECT entrydate, job FROM tb_emp WHERE name = &#x27;张三&#x27;);<br></code></pre></td></tr></table></figure>



<h4 id="7-3-4-表子查询"><a href="#7-3-4-表子查询" class="headerlink" title="7.3.4 表子查询"></a>7.3.4 表子查询</h4><p>表子查询是指子查询返回的结果是多行多列，常作为临时表。</p>
<p>常用的操作符：<code>IN</code></p>
<p><strong>案例1：</strong> 查询入职日期是“2021-03-01” 之后的员工名字，入职日期，及其部门名称</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs mysql">-- 第1步 查询入职日期是 2021-03-01 之后的员工名字，入职日期和部门ID<br>SELECT name, entrydate, dept_id<br>FROM tb_emp <br>WHERE entrydate &gt; &#x27;2021-03-01&#x27;;<br></code></pre></td></tr></table></figure>

<p>查询结果</p>
<figure class="highlight gherkin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs gherkin">+-------+------------+--------+<br>|<span class="hljs-string"> name </span>|<span class="hljs-string"> entrydate   </span>|<span class="hljs-string"> dept_id </span>|<br>+-------+------------+--------+<br>|<span class="hljs-string"> 张三  </span>|<span class="hljs-string"> 2022-01-01 </span>|<span class="hljs-string">      1 </span>|<br>|<span class="hljs-string"> 李四  </span>|<span class="hljs-string"> 2022-01-01 </span>|<span class="hljs-string">      2 </span>|<br>|<span class="hljs-string"> 王五  </span>|<span class="hljs-string"> 2022-01-01 </span>|<span class="hljs-string">      3 </span>|<br>|<span class="hljs-string"> 赵六  </span>|<span class="hljs-string"> 2022-01-01 </span>|<span class="hljs-string">      4 </span>|<br>|<span class="hljs-string"> 陈七  </span>|<span class="hljs-string"> 2024-03-13 </span>|<span class="hljs-string">      0 </span>|<br>+-------+------------+--------+<br></code></pre></td></tr></table></figure>



<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs mysql">-- 第2步 将上面的结果作为临时表，然后继续查询部门名称<br>SELECT emp.name, emp.entrydate, dept.name<br>FROM (SELECT * FROM tb_emp WHERE entrydate &gt; &#x27;2021-03-01&#x27;) emp, tb_dept dept <br>WHERE emp.dept_id = dept.id;<br></code></pre></td></tr></table></figure>

<p>查询结果</p>
<figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs asciidoc"><span class="hljs-code">+-------+</span>------------<span class="hljs-code">+--------+</span><br><span class="hljs-section">| name | entrydate   | name  |</span><br><span class="hljs-section">+-------+------------+--------+</span><br>| 张三  | 2022-01-01 | 技术部 |<br>| 李四  | 2022-01-01 | 人事部 |<br>| 王五  | 2022-01-01 | 财务部 |<br><span class="hljs-section">| 赵六  | 2022-01-01 | 市场部 |</span><br><span class="hljs-section">+-------+------------+--------+</span><br></code></pre></td></tr></table></figure>

<p>上面的语句可能会忽略不属于任何部门的员工，接下来改为左连接查询即可解决这种情况：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SELECT emp.name, emp.entrydate, dept.name<br>FROM tb_emp emp<br>LEFT JOIN tb_dept dept<br>ON emp.dept_id = dept.id<br>WHERE entrydate &gt; &#x27;2021-03-01&#x27;;<br></code></pre></td></tr></table></figure>

<p>查询结果</p>
<figure class="highlight gherkin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs gherkin">+-------+------------+--------+<br>|<span class="hljs-string"> name </span>|<span class="hljs-string"> entrydate   </span>|<span class="hljs-string"> name  </span>|<br>+-------+------------+--------+<br>|<span class="hljs-string"> 张三  </span>|<span class="hljs-string"> 2022-01-01 </span>|<span class="hljs-string"> 技术部 </span>|<br>|<span class="hljs-string"> 李四  </span>|<span class="hljs-string"> 2022-01-01 </span>|<span class="hljs-string"> 人事部 </span>|<br>|<span class="hljs-string"> 王五  </span>|<span class="hljs-string"> 2022-01-01 </span>|<span class="hljs-string"> 财务部 </span>|<br>|<span class="hljs-string"> 赵六  </span>|<span class="hljs-string"> 2022-01-01 </span>|<span class="hljs-string"> 市场部 </span>|<br>|<span class="hljs-string"> 陈七  </span>|<span class="hljs-string"> 2024-03-13 </span>|<span class="hljs-string"> NULL   </span>|<br>+-------+------------+--------+<br></code></pre></td></tr></table></figure>



<h2 id="8、MySQL-事务"><a href="#8、MySQL-事务" class="headerlink" title="8、MySQL 事务"></a>8、MySQL 事务</h2><p><strong>事务是一组操作的集合，是一个不可分割的工作单位</strong>。事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求，即这些操作<strong>要么同时成功，要么同时失败</strong>。</p>
<p><strong>注意事项：</strong></p>
<p>默认情况下，MySQL的事务是自动提交的，即当执行一条 DML 语句，MySQL会立即隐式的提交事务。</p>
<p><strong>事务控制：</strong></p>
<ul>
<li>开启事务：<code>start transaction; / begin;</code></li>
<li>提交事务：<code>commit;</code></li>
<li>回滚事务：<code>rollback;</code></li>
</ul>
<h3 id="8-1-四个事务特性"><a href="#8-1-四个事务特性" class="headerlink" title="8.1 四个事务特性"></a>8.1 四个事务特性</h3><p>事务有四个特性 ACID 分别是：</p>
<ul>
<li><strong>原子性：</strong>事务是不可分割的最小单元，要么全部成功，要么全部失败。</li>
<li><strong>一致性：</strong> 事务完成时，必须使所有的数据都保持一致状态。</li>
<li><strong>隔离性：</strong> 数据库系统提供的隔离机制，保证事务在不受外部并发操作影响的独立环境下运行。</li>
<li><strong>持久性：</strong> 事务一旦提交或回滚，它对数据库中的数据的改变就是永久的。</li>
</ul>
<h3 id="8-2-数据库索引"><a href="#8-2-数据库索引" class="headerlink" title="8.2 数据库索引"></a>8.2 数据库索引</h3><p>索引（index）是帮助数据库 高效获取数据 的数据结构。  </p>
<p><img src="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403130458224.png" srcset="/img/loading.gif" lazyload alt="image-20240313045826879"></p>
<p><strong>优点：</strong></p>
<ul>
<li>提高数据查询的效率，降低数据库的 IO 成本。</li>
<li>通过 索引列对数据进行排序，降低数据排序的成本，降低 CPU 消耗。</li>
</ul>
<p><strong>缺点：</strong></p>
<ul>
<li>索引会占用存储空间</li>
<li>索引大大提高了查询效率，同时却也降低了 DML中 insert、update 和 delete 的效率。</li>
</ul>
<p><strong>索引结构：</strong></p>
<p>MySQL 数据库支持的索引结构有很多，如：</p>
<p>Hash 索引、B+Tree 索引、Full-Text索引等。我们平时所说的索引，若没有特别指明，都是指默认的 <code>B+Tree </code>结构组织的索引。</p>
<p><img src="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403130504081.png" srcset="/img/loading.gif" lazyload alt="image-20240313050450899"></p>
<p>大数据量情况下，层级深，检索速度慢。</p>
<h4 id="8-2-1-B-Tree-多路平衡搜索树"><a href="#8-2-1-B-Tree-多路平衡搜索树" class="headerlink" title="8.2.1 B+Tree 多路平衡搜索树"></a>8.2.1 B+Tree 多路平衡搜索树</h4><p>B+Tree 结构图：</p>
<p><img src="https://uni-pic-bed.oss-cn-hangzhou.aliyuncs.com/blog2024/202403130506375.png" srcset="/img/loading.gif" lazyload alt="image-20240313050619116"></p>
<p><strong>B+Tree 特点：</strong></p>
<ul>
<li>每一个节点，可以存储多个 key（有n个key，就有n个指针）。</li>
<li>所有的数据都存储在叶子节点，非叶子节点仅用于索引数据。</li>
<li>叶子节点形成了一颗双向链表，便于数据的排序及区间范围查询。</li>
</ul>
<h3 id="8-3-索引的语法"><a href="#8-3-索引的语法" class="headerlink" title="8.3  索引的语法"></a>8.3  索引的语法</h3><p>MySQL 索引主要有三个操作：</p>
<ul>
<li><p><strong>创建索引</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">CREATE [UNIQUE] INDEX 索引名 ON 表名(字段名...);<br></code></pre></td></tr></table></figure>

<p><strong>案例：</strong>为本篇文章 7. 多表查询部分提供的数据表 tb_emp 的name字段建立一个索引</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">CREATE INDEX idx_emp ON tb_emp(name);<br></code></pre></td></tr></table></figure>
</li>
<li><p><strong>查看索引</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SHOW INDEX FROM 表名;<br></code></pre></td></tr></table></figure>

<p><strong>案例：</strong> 查询 tb_emp 表的索引信息</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">SHOW INDEX FROM tb_emp;<br></code></pre></td></tr></table></figure>
</li>
<li><p><strong>删除索引</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">DROP INDEX 索引名 ON 表名;<br></code></pre></td></tr></table></figure>

<p><strong>案例：</strong>删除刚才创建的索引表</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">DROP INDEX idx_emp_name;<br></code></pre></td></tr></table></figure></li>
</ul>
<p><strong>注意事项：</strong></p>
<ul>
<li>主键字段，在建表时，会自动创建主键索引。</li>
<li>添加唯一的约束时，数据库实际上会添加唯一索引。</li>
</ul>

                
              </div>
            
            <hr/>
            <div>
              <div class="post-metas my-3">
  
    <div class="post-meta mr-3 d-flex align-items-center">
      <i class="iconfont icon-category"></i>
      

<span class="category-chains">
  
  
    
      <span class="category-chain">
        
  <a href="/categories/MySQL/" class="category-chain-item">MySQL</a>
  
  

      </span>
    
  
</span>

    </div>
  
  
    <div class="post-meta">
      <i class="iconfont icon-tags"></i>
      
        <a href="/tags/MySQL/" class="print-no-link">#MySQL</a>
      
        <a href="/tags/%E5%A4%9A%E8%A1%A8%E6%9F%A5%E8%AF%A2/" class="print-no-link">#多表查询</a>
      
    </div>
  
</div>


              
  

  <div class="license-box my-3">
    <div class="license-title">
      <div>MySQL 学习笔记1 | 数据库、约束、常见数据类型、DDL、DML、DQL、MySQL多表设计、多表查询、MySQL事务、索引</div>
      <div>http://example.com/2024/03/13/MySQL-学习笔记1-数据库、约束、常见数据类型、DDL、DML、DQL、MySQL多表设计、多表查询、MySQL事务、索引/</div>
    </div>
    <div class="license-meta">
      
        <div class="license-meta-item">
          <div>作者</div>
          <div>十一的蛋炒饭</div>
        </div>
      
      
        <div class="license-meta-item license-meta-date">
          <div>发布于</div>
          <div>2024年3月13日</div>
        </div>
      
      
      
        <div class="license-meta-item">
          <div>许可协议</div>
          <div>
            
              
              
                <a class="print-no-link" target="_blank" href="https://creativecommons.org/licenses/by/4.0/">
                  <span class="hint--top hint--rounded" aria-label="BY - 署名">
                    <i class="iconfont icon-by"></i>
                  </span>
                </a>
              
            
          </div>
        </div>
      
    </div>
    <div class="license-icon iconfont"></div>
  </div>



              
                <div class="post-prevnext my-3">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/2024/03/15/BUG%E8%AE%B0%E5%BD%9514-%E4%BD%BF%E7%94%A8-MyBatis-%E6%9F%A5%E8%AF%A2%E4%B8%8D%E5%88%B0%E6%95%B0%E6%8D%AE%E5%BA%93%E9%87%8C%E7%9A%84%E4%B8%AD%E6%96%87%E6%95%B0%E6%8D%AE/" title="BUG记录14 | 使用 MyBatis 查询不到数据库里的中文数据">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">BUG记录14 | 使用 MyBatis 查询不到数据库里的中文数据</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2024/03/12/Web-%E5%BC%80%E5%8F%91%E7%AC%94%E8%AE%B03-Postman-%E3%80%81SpringBoot-%E8%8E%B7%E5%8F%96%E4%B8%8D%E5%90%8C%E7%9A%84%E8%AF%B7%E6%B1%82%E5%8F%82%E6%95%B0%E3%80%81Spring-Boot-%E5%93%8D%E5%BA%94%E6%95%B0%E6%8D%AE%E3%80%81Spring-%E7%9A%84-IOC%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC%E5%92%8CDI-%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5%E3%80%81%E9%A1%B9%E7%9B%AE%E5%88%86%E5%B1%82%E8%A7%A3%E8%80%A6%E7%9A%84%E5%AE%9E%E7%8E%B0%E3%80%81Bean-%E6%B3%A8%E5%85%A5%E7%9A%84%E6%B3%A8%E8%A7%A3/" title="Web 开发笔记3 | Postman 、SpringBoot 获取不同的请求参数、Spring Boot 响应数据、Spring 的 IOC控制反转和DI 依赖注入、项目分层解耦的实现、Bean 注入的注解">
                        <span class="hidden-mobile">Web 开发笔记3 | Postman 、SpringBoot 获取不同的请求参数、Spring Boot 响应数据、Spring 的 IOC控制反转和DI 依赖注入、项目分层解耦的实现、Bean 注入的注解</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>

    <div class="side-col d-none d-lg-block col-lg-2">
      
  <aside class="sidebar" style="margin-left: -1rem">
    <div id="toc">
  <p class="toc-header">
    <i class="iconfont icon-list"></i>
    <span>目录</span>
  </p>
  <div class="toc-body" id="toc-body"></div>
</div>



  </aside>


    </div>
  </div>
</div>





  



  



  



  



  







    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v" for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>

    

    
  </main>

  <footer>
    <div class="footer-inner">
  
    <div class="footer-content">
       <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>博客网站基于Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>主题Fluid</span></a> 
    </div>
  
  
  
  
</div>

  </footer>

  <!-- Scripts -->
  
  <script  src="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://lib.baomitu.com/jquery/3.6.4/jquery.min.js" ></script>
<script  src="https://lib.baomitu.com/twitter-bootstrap/4.6.1/js/bootstrap.min.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>





  
    <script  src="/js/img-lazyload.js" ></script>
  




  
<script>
  var relativeDate = function() {
    var updatedTime = document.getElementById('updated-time');
    if (updatedTime) {
      var text = updatedTime.textContent;
      var reg = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:Z|[+-]\d{2}:\d{2})/;
      var matchs = text.match(reg);
      if (matchs) {
        var relativeTime = moment(matchs[0]).fromNow();
        updatedTime.textContent = text.replace(reg, relativeTime);
      }
      updatedTime.style.display = '';
    }
  };
  Fluid.utils.createScript('https://lib.baomitu.com/moment.js/2.29.4/moment.min.js', function() {
    if (!'zh-cn'.startsWith('en')) {
      Fluid.utils.createScript('https://lib.baomitu.com/moment.js/2.29.4/locale/zh-cn.min.js', function() {
        relativeDate();
      });
    } else {
      relativeDate();
    }
  });
</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/tocbot/4.20.1/tocbot.min.js', function() {
    var toc = jQuery('#toc');
    if (toc.length === 0 || !window.tocbot) { return; }
    var boardCtn = jQuery('#board-ctn');
    var boardTop = boardCtn.offset().top;

    window.tocbot.init(Object.assign({
      tocSelector     : '#toc-body',
      contentSelector : '.markdown-body',
      linkClass       : 'tocbot-link',
      activeLinkClass : 'tocbot-active-link',
      listClass       : 'tocbot-list',
      isCollapsedClass: 'tocbot-is-collapsed',
      collapsibleClass: 'tocbot-is-collapsible',
      scrollSmooth    : true,
      includeTitleTags: true,
      headingsOffset  : -boardTop,
    }, CONFIG.toc));
    if (toc.find('.toc-list-item').length > 0) {
      toc.css('visibility', 'visible');
    }

    Fluid.events.registerRefreshCallback(function() {
      if ('tocbot' in window) {
        tocbot.refresh();
        var toc = jQuery('#toc');
        if (toc.length === 0 || !tocbot) {
          return;
        }
        if (toc.find('.toc-list-item').length > 0) {
          toc.css('visibility', 'visible');
        }
      }
    });
  });
</script>


  <script src=https://lib.baomitu.com/clipboard.js/2.0.11/clipboard.min.js></script>

  <script>Fluid.plugins.codeWidget();</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/anchor-js/4.3.1/anchor.min.js', function() {
    window.anchors.options = {
      placement: CONFIG.anchorjs.placement,
      visible  : CONFIG.anchorjs.visible
    };
    if (CONFIG.anchorjs.icon) {
      window.anchors.options.icon = CONFIG.anchorjs.icon;
    }
    var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
    var res = [];
    for (var item of el) {
      res.push('.markdown-body > ' + item.trim());
    }
    if (CONFIG.anchorjs.placement === 'left') {
      window.anchors.options.class = 'anchorjs-link-left';
    }
    window.anchors.add(res.join(', '));

    Fluid.events.registerRefreshCallback(function() {
      if ('anchors' in window) {
        anchors.removeAll();
        var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
        var res = [];
        for (var item of el) {
          res.push('.markdown-body > ' + item.trim());
        }
        if (CONFIG.anchorjs.placement === 'left') {
          anchors.options.class = 'anchorjs-link-left';
        }
        anchors.add(res.join(', '));
      }
    });
  });
</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js', function() {
    Fluid.plugins.fancyBox();
  });
</script>


  <script>Fluid.plugins.imageCaption();</script>

  <script  src="/js/local-search.js" ></script>





<!-- 主题的启动项，将它保持在最底部 -->
<!-- the boot of the theme, keep it at the bottom -->
<script  src="/js/boot.js" ></script>


  

  <noscript>
    <div class="noscript-warning">博客在允许 JavaScript 运行的环境下浏览效果更佳</div>
  </noscript>
</body>
</html>
